﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using TotalLMS.Util;

namespace TotalLMS.Datamodels.cmi
{
    public class DMErrorManager
    {

        private static String currentErrorCode;

        private static String[][] errors = new String[][] 
   {
      new String[] {"0", "No Error", "The previous LMS API Function call completed successfully."},
      new String[] {"101", "General Exception", "An unspecified, unexpected exception has occurred."},
      new String[] {"201", "Invalid argument error", ""},
      new String[] {"202", "Element cannot have children", ""},
      new String[] {"203", "Element not an array - cannot have count", ""},
      new String[] {"301", "Not initialized", "The LMS is not initialized."},
      new String[] {"401", "Not implemented error", "The data model element in question was not implemented."},
      new String[] {"402", "Invalid set value, element is a keyword", "Trying to set a reserved keyword in the data model. Trying to set a keyword (_count, _children, or _version). This is prohibited."},
      new String[] {"403", "Element is read only","Data Element is Read Only (Not Writeable). Cannot call LMSSetValue() for the element in question."},
      new String[] {"404", "Element is write only", "Data Element is Write Only (Not Readable). Cannot call LMSGetValue() for the element in question."},
      new String[] {"405", "Incorrect Data Type", "Invalid Type being used for setting element. The type being used as the set value argument does not match that of the element being set."  }
   };

        /*****************************************************************************
        **
        ** Method:  DMErrorManager()
        ** Input:   none
        ** Output:  none
        **
        ** Description:
        ** Default Constructor - intializes the current error code to "No Error".
        **
        *****************************************************************************/
        public DMErrorManager()
        {
            currentErrorCode = "0";
        }

        /*****************************************************************************
        **
        ** Method:  recNotImplementedError()
        ** Input:   CMIRequest theRequest: the request being processed
        ** Output:  none
        **
        ** Description:
        **   Records the appropriate Not Implemented error
        *****************************************************************************/
        public void recNotImplementedError(CMIRequest theRequest)
        {
            if (theRequest.isAChildrenRequest())
            {
                if (DebugIndicator.ON)
                {
                    Console.WriteLine("Trying to get/set an _children element.\n  This keyword is not permitted to be implemented on the given element");
                }

                SetCurrentErrorCode("401");
            }
            else if (theRequest.isACountRequest())
            {
                if (DebugIndicator.ON)
                {
                    Console.WriteLine("Trying to get/set an _count element.\n  This keyword is not permitted to be implemented on the given element");
                }
                SetCurrentErrorCode("401");
            }
            else
            {
                // Notify error manager
                SetCurrentErrorCode("401");
            }

        }

        /*****************************************************************************
        **
        ** Method:  recKeyWordError()
        ** Input:   String inElement: element being processed
        ** Output:  none
        **
        ** Description:
        **   Determines which keyword (_children, _count, _version) is being processed
        **   and sets the correct error code
        **
        *****************************************************************************/
        public void recKeyWordError(String inElement)
        {
            if (inElement.Equals("_children"))
            {
                if (DebugIndicator.ON)
                {
                    Console.WriteLine("Trying to set an _children element.  This action is not permitted!");
                }
                SetCurrentErrorCode("402");
            }
            else if (inElement.Equals("_count"))
            {
                if (DebugIndicator.ON)
                {
                    Console.WriteLine("Trying to set an _count element.  This action is not permitted!");
                }
                SetCurrentErrorCode("402");
            }
            else
            {
                if (DebugIndicator.ON)
                {
                    Console.WriteLine("Trying to set an _version element.  This action is not permitted!");
                }
                SetCurrentErrorCode("402");
            }

        }

        /*****************************************************************************
        **
        ** Method:  recGetKeyWordError()
        ** Input:   String inElement: element being processed
        ** Output:  none
        **
        ** Description:
        **   Determines which keyword (_children, _count, _version) is being processed
        **   and sets the correct error code
        **
        *****************************************************************************/
        public void recGetKeyWordError(String inElement)
        {
            if (inElement.Equals("_children"))
            {
                if (DebugIndicator.ON)
                {
                    Console.WriteLine("Trying to get an _children element.  This action is not permitted!");
                }
                SetCurrentErrorCode("202");
            }
            else if (inElement.Equals("_count"))
            {
                if (DebugIndicator.ON)
                {
                    Console.WriteLine("Trying to get an _count element.  This action is not permitted!");
                }
                SetCurrentErrorCode("203");
            }
            else
            {
                if (DebugIndicator.ON)
                {
                    Console.WriteLine("Trying to get an _version element.  This action is not permitted!");
                }
                SetCurrentErrorCode("401");
            }

        }

        /*****************************************************************************
        **
        ** Method:  GetCurrentErrorCode()
        ** Input:   none
        ** Output:  String - current error code
        **
        ** Description:
        ** Returns the value of the Current Error Code that was set by the most
        ** recent API call.
        **
        *****************************************************************************/
        public String GetCurrentErrorCode()
        {
            return currentErrorCode;
        }

        /*****************************************************************************
        **
        ** Method:  SetCurrentErrorCode(String code)
        ** Input:   String code - The error code (from the predefined list of codes)
        ** Output:  none
        **
        ** Description:
        ** Sets the value of the Current Error Code.
        **
        *****************************************************************************/
        public void SetCurrentErrorCode(String code)
        {
            currentErrorCode = code;
        }

        /*****************************************************************************
        **
        ** Method:  ClearCurrentErrorCode()
        ** Input:   none
        ** Output:  none
        **
        ** Description:
        ** Sets the value of the Current Error Code to "No Error".
        **
        *****************************************************************************/
        public void ClearCurrentErrorCode()
        {
            currentErrorCode = errors[0][0];
        }


        /*****************************************************************************
        **
        ** Method:  GetErrorDescription(String code)
        ** Input:   String code - error code
        ** Output:  String - the description associated with the given error code
        **
        ** Description:
        ** Retrieves and returns the text associated with the given error code
        **
        *****************************************************************************/
        public String GetErrorDescription(String code)
        {
            // retrieves and returns the description of the provided error code
            return GetErrorElement(code)[1];
        }

        /*****************************************************************************
        **
        ** Method:  GetErrorDiagnostic(String code)
        ** Input:   String code - error code
        ** Output:  String - the diagnostic text associated with the given error code
        **
        ** Description:
        ** Retrieves and returns the diagnostic text associated with the error code
        **
        *****************************************************************************/
        public String GetErrorDiagnostic(String code)
        {
            return GetErrorElement(code)[2];
        }

        /*****************************************************************************
        **
        ** Method:  GetErrorElement(String code)
        ** Input:   String code - error code
        ** Output:  String[] - the array corresponding to the element identified by
        **                     the given error code
        **
        ** Description:
        ** Private function that gets the array containing the error element info
        ** identified by the given error code
        **
        *****************************************************************************/
        private String[] GetErrorElement(String code)
        {
            for (int i = 0; i < errors.Length; i++)
            {
                if (errors[i][0].Equals(code) == true)
                    return errors[i] ;
            }

            String[] tmp = { "", "", "" };
            return tmp;
        }

        /*****************************************************************************
        **
        ** Method:  isValidErrorCode()
        ** Input:   String errorCode
        ** Output:  boolean indicating whether or not the error code is valid
        **
        ** Description:
        **   Determines whether or not the Error Code passed in is a valid SCORM
        **   error code.
        **
        *****************************************************************************/
        public bool isValidErrorCode(String errorCode)
        {
            bool result = false;
            int i = 0;

            while (!result && (i < errors.Length))
            {
                if (errors[i][0].Equals(errorCode) == true)
                {
                    result = true;
                }
                i++;
            }

            return result;
        }
    }
}
